(ns clojure-demo.core
  (:use [clojure.java.io]))


(set! *warn-on-reflection* true)

; (def rdr (reader "E:\work-my\java-lib-git\readme.txt" :encoding "utf-8"))
; (clojure.string/replace "hello\r\n xxyy" #"[\r\n]" "")

(def bytesString
  (->
    (slurp "E:\\work-my\\java-asn1-tcpip\\java-netprotocol-ui\\org\\hxzon\\ui\\util\\goose.1.hex.txt")
    (clojure.string/replace #"[\r\n ]" "")
    )
  )
(prn bytesString)

; (let [ch (int \a)] ch)

;will error
#_ (defn ch>= ^boolean [^char ch1 ^char ch2]
     (>= (byte ch1) (byte ch2))
     )

(defn ch>= ^Boolean [^Character ch1 ^Character ch2]
  (>= (int ch1) (int ch2)))

(defn ch<= ^Boolean [^Character ch1 ^Character ch2]
  (<= (int ch1) (int ch2)))

(defn ch+ ^long [^Character ch1 ^Character ch2]
  (+ (int ch1) (int ch2)))

(defn ch- ^long [^Character ch1 ^Character ch2]
  (- (int ch1) (int ch2)))

(defn fromHexChar ^Byte [^Character ch ^Boolean high]
  (let [^long result
        (cond
          (and (ch>= ch \A) (ch<= ch \F))
          (ch+ (ch- ch \A) 10)
          (and (ch>= ch \a) (ch<= ch \f))
          (ch+ (ch- ch \a) 10)
          (and (ch>= ch \0) (ch<= ch \9))
          (ch- ch \0)
          :else (throw (IllegalArgumentException. (str ch ">16 or < 0")))
          )
        ]
    (cond high
      (unchecked-byte (bit-shift-left result 4))
      :else (byte result)
      )
    )
  )

(defn fromHexCharArray
  (^Byte [^Character ch1 ^Character ch2]
    (byte (bit-xor (fromHexChar ch1 true) (fromHexChar ch2 false))))
  (^bytes [^chars chs]
    (let [result (byte-array (/ (alength chs) 2))]
      (dotimes [i (alength result)]
        (aset result i (fromHexCharArray (aget chs (* i 2)) (aget chs (+ 1 (* i 2)))))
        )
      result
      )
    )
  )


(defn fromHexString ^chars [^String s]
  (fromHexCharArray (.toCharArray s)))

(defn toHexChar ^Character [^Byte orig]
  (cond
    (or (> orig 16) (< orig 0))
    (throw (IllegalArgumentException. (str orig ">16 or <0")))
    (< orig 10)
    (char (+ orig (int \0)))
    :else (char (+ (- orig 10) (int \a))))
  )

(defn getHighHexChar ^Character [^Byte orig]
  (toHexChar (bit-shift-right (bit-and orig 0xf0) 4)))

(defn getLowHexChar ^Character [^Byte orig]
  (toHexChar (bit-and orig 0x0f)))

(defn toHexCharArray ^chars [^Character orig]
  (char-array 2 [(getHighHexChar orig) (getLowHexChar orig)]))


(defn implToDisplayHexString ^CharSequence [^bytes orig offset len lineLen split lineSplit]
  (let [buffer (StringBuffer.) lastIndex (- lineLen 1)]
    ;(prn (format "%d,%d,%d,%s,%s,%d" offset len lineLen split lineSplit lastIndex))
    (dotimes [i (alength orig)]
      (.append buffer (char-array 2 (toHexCharArray (aget orig (+ offset i)))))
      (.append buffer split)
      (if (= (mod i lineLen) lastIndex) (.append buffer lineSplit))
      )
    buffer))

(defn toDisplayHexString ^CharSequence [^bytes orig]
  (implToDisplayHexString orig 0 (alength orig) 16 "" "\r\n"))

;(prn (.toString (.append (StringBuffer.) (char-array 2 [\a \c]))))
;(prn (.toString (.append (StringBuffer.) (char-array 2 [(getHighHexChar 12) (getLowHexChar 12) ]))))
;(prn (.toString (.append (StringBuffer.) (char-array 2 [(getHighHexChar 12) (getLowHexChar 12) ]))))
;(prn (.toString (.append (StringBuffer.) (toHexCharArray 12) )))
; (prn (.toString (.append (StringBuffer.) (char-array 2 (toHexCharArray 12)) )))
(-> bytesString fromHexString toDisplayHexString .toString prn)

